<!DOCTYPE html>
<html>
<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<style type="text/css">
		@import url(./../lib/Cesium/Widgets/widgets.css);

		body,
		html,
		#map {
			width: 100%;
			height: 100%;
			overflow: hidden;
			margin: 0;
			font-family: "微软雅黑";
		}
	</style>


	<title>材质(Material)</title>
</head>

<body onload="onload()">
	<script src="./../lib/lodash.min.js"></script>
	<script src='./../lib/threejs/three.js'></script>
	<script src='./../lib/threejs/stats.min.js'></script>
	<script src='./../lib/threejs/dat.gui.min.js'></script>
</body>

</html>
<script type="text/javascript">

	let renderer, camera, scene, stats, gui,
		rotate = true, step = 0, gType = "box", mColor = "#00ffff", mType = '法向材质', material,
		controls, w = window.innerWidth, h = window.innerHeight, geometry;


	function initRenderer() {
		renderer = new THREE.WebGLRenderer();
		renderer.setSize(w, h);
		document.body.appendChild(renderer.domElement);
	}
	function initCamera() {
		camera = new THREE.PerspectiveCamera(45, w / h, 0.1, 300);
		camera.position.set(0, 0, 150)
	}
	function initScene() {
		scene = new THREE.Scene();
	}

	function initGUI() {
		controls = {
			rotate: true,
			geometry: "box",
			mType: '法向材质',
			mColor: "#00ffff",
			metalness: 0.1,
			metalnessMap: 0.1
		}
		gui = new dat.GUI();
		gui.add(controls, "rotate").name("旋转").onChange(e => {
			rotate = e;
		})
		gui.add(controls, "geometry", ["box", "circle", "cone", "cylinder", "sphere", "plane", "torus", "line", "dashline"]).name("模型").onChange(e => {
			gType = e;
			if (gType == "line") {
				mType = "线条材质"
			} else if (gType == "dashline") {
				mType = "虚线"
			}  
		})
		gui.add(controls, "mType", ["法向材质", "线条材质", "虚线", "兰伯特材质", "高光材质", "PBR材质"]).name("类型").onChange(e => {
			mType = e;
			if (mType == "线条材质") {
				gType = "line"
			} else if (mType == "虚线") {
				gType = "dashline"
			} 
		})
		gui.addColor(controls, "mColor").name("颜色").onChange(e => {
			mColor = e;
		})
		let pbrFolder = gui.addFolder("PBR材质")
		pbrFolder.add(controls, "metalness", 0, 1).name("光滑度").onChange(e => {
			material.metalness = e; //设置的值的范围为0-1，值越小，材质越光滑，高光越明显
			material.needsUpdate=true;
		})
		// pbrFolder.add(controls, "metalnessMap", 0, 1).name("质感").onChange(e => {
		// 	material.metalnessMap = e; //设置的值的范围为0-1，值越大，越有生锈金属的质感，值越小反光越清晰
		// })
	}
	function initStats() {
		stats = new Stats();
		document.body.appendChild(stats.dom)
	}


	function animation() {
		requestAnimationFrame(animation)

		initMesh();
		getMaterial();

		if (rotate && geometry) {
			step += 0.002;
			geometry.rotation.set(step, step, step);
		}

		stats.update();
		renderer.render(scene, camera)
	}

	function resetSize() {

		w = window.innerWidth;
		h = window.innerHeight;
		renderer.setSize(w, h);
		initCamera();

	}

	function initLight() {
		let dirLight = new THREE.DirectionalLight(0xffffff);//添加了一个白色的平行光
		dirLight.position.set(20, 50, 50);
		scene.add(dirLight);

		scene.add(new THREE.AmbientLight(0x222222));//添加一个全局环境光
	}

	function initMesh() {


		geometry && scene.remove(geometry);

		switch (gType) {
			case "box":
				//创建立方体
				geometry = new THREE.Mesh(new THREE.BoxGeometry(50, 50, 50), material);
				break;
			case "circle":
				//创建圆
				geometry = new THREE.Mesh(new THREE.CircleGeometry(15, 32), material);
				break;
			case "cone":
				//创建圆锥
				geometry = new THREE.Mesh(new THREE.ConeGeometry(15, 20, 32), material);
				break;
			case "cylinder":
				//创建圆柱
				geometry = new THREE.Mesh(new THREE.CylinderGeometry(15, 15, 30, 42), material);
				break;
			case "sphere":
				//创建球
				geometry = new THREE.Mesh(new THREE.SphereGeometry(15, 32, 32), material);
				break;
			case "plane":
				//创建平面
				geometry = new THREE.Mesh(new THREE.PlaneGeometry(50, 50), material);
				break;
			case "torus":
				//创建圆环
				geometry = new THREE.Mesh(new THREE.TorusGeometry(10, 3, 16, 100), material);
				break;
			case "line":
				//添加直线
				var pointsArr = [
					new THREE.Vector3(-10, 0, -5),
					new THREE.Vector3(-5, 15, 5),
					new THREE.Vector3(20, 15, -5),
					new THREE.Vector3(10, 0, 5)
				];
				var lineGeometry = new THREE.Geometry(); //实例化几何体
				lineGeometry.setFromPoints(pointsArr); //使用当前点的属性配置几何体 
				geometry = new THREE.Line(lineGeometry, material);
				break;
			case "dashline":
				var pointsArr = [
					new THREE.Vector3(-10, 0, -5),
					new THREE.Vector3(-5, 15, 5),
					new THREE.Vector3(20, 15, -5),
					new THREE.Vector3(10, 0, 5)
				];
				//指定一些用于生成曲线线的三维顶点
				var curve = new THREE.CatmullRomCurve3(pointsArr);

				var points = curve.getPoints(50); //使用getPoints获取当前曲线分成50段后的所有顶点
				var curveGeometry = new THREE.BufferGeometry().setFromPoints(points); //使用顶点生成几何体


				// 使用THREE.Line创建线
				geometry = new THREE.Line(curveGeometry, material);
				geometry.computeLineDistances(); //需要重新计算位置才能显示出虚线 

				break;
		}

		geometry.position.set(0, 20, 0);
		scene.add(geometry);

	}

	function getMaterial() { 
		switch (mType) {
			case "法向材质":
				material = new THREE.MeshNormalMaterial();
				break;
			case "线条材质":
				material = new THREE.LineBasicMaterial({color: new THREE.Color(mColor)}); //材质  
				gType = "line";
				break;
			case "虚线":
				material = new THREE.LineDashedMaterial({color: new THREE.Color(mColor)}); //材质  
				gType = "dashline";
				break;
			case "兰伯特材质":
				material = new THREE.MeshLambertMaterial({color: new THREE.Color(mColor)}); //材质  
				break;
			case "高光材质":
				material = new THREE.MeshPhongMaterial({color: new THREE.Color(mColor)}); //材质  
				break;
			case "PBR材质":
				material = new THREE.MeshPhysicalMaterial({color: new THREE.Color(mColor)}); //材质  
				material.metalness = 0.1; //设置的值的范围为0-1，值越小，材质越光滑，高光越明显
				// material.metalnessMap = 0.1; //设置的值的范围为0-1，值越大，越有生锈金属的质感，值越小反光越清晰
				break;

		}

	}


	function onload() {
		initRenderer();
		initCamera();
		initScene();
		initStats();
		initGUI();
		initLight();
		animation();
		window.onresize = resetSize;

	}

</script>